/*********************************************************************************************************************
* seekfree_stc32g_wireless_charge_opensource_software 即（STC32G 无线充电开源软件）
* 是一个基于官方 SDK 接口的开源软件
* Copyright (c) 2022 SEEKFREE 逐飞科技
* 
* 本文件是 STC32G 无线充电开源软件的一部分
* 
* STC32G 无线充电开源软件 是免费软件
* 您可以根据自由软件基金会发布的 GPL（GNU General Public License，即 GNU通用公共许可证）的条款
* 即 GPL 的第3版（即 GPL3.0）或（您选择的）任何后来的版本，重新发布和/或修改它
* 
* 本开源库的发布是希望它能发挥作用，但并未对其作任何的保证
* 甚至没有隐含的适销性或适合特定用途的保证
* 更多细节请参见 GPL
* 
* 您应该在收到本开源库的同时收到一份 GPL 的副本
* 如果没有，请参阅<https://www.gnu.org/licenses/>
* 
* 额外注明：
* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本
* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中
* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件
* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明（即本声明）
* 
* 文件名称          display_handler
* 公司名称          成都逐飞科技有限公司
* 版本信息          查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境          MDK 5.37
* 适用平台          STC32G
* 店铺链接          https://seekfree.taobao.com/
* 
* 修改记录
* 日期              作者                备注
* 2023-01-04        Teternal            first version
* 2024-11-28        Teternal            STC32G migration
********************************************************************************************************************/

#include "zf_gpio.h"

#include "driver_interface.h"
#include "charge_control.h"
#include "display_handler.h"
#include "power_sample.h"

#pragma warning disable = 183
#pragma warning disable = 177

static display_mode_enum    display_mode_select     =   DISPLAY_MODE_DEC;
static uint8                display_index           =   0;
static uint8                display_temp            =   0;

// 共阳数码管 阴极接IO
// 所以是低电平点亮
// 各段与数据位数对应关系如下
//  -       1
// | |     6 2
//  -       7
// | |     5 3
//  - .     4 8
const uint8 digital_tube_font[] =
{
//  '0'     '1'     '2'     '3'
    0xC0,   0xF9,   0xA4,   0xB0,
//  '4'     '5'     '6'     '7'
    0x99,   0x92,   0x82,   0xF8,
//  '8'     '9'     'A'     'b'
    0x80,   0x90,   0x88,   0x83,
//  'C'     'd'     'E'     'F'
    0xC6,   0xA1,   0x86,   0x8E,
//  '-'     ' '     'r'     'L'
    0xBF,   0xFF,   0xAF,   0xC7
};

//-------------------------------------------------------------------------------------------------------------------
// 函数简介     显示处理 数码管显示函数 根据索引显示对应字符
// 参数说明     index       显示索引 0-十位 1-个位
// 参数说明     data        数据 0-17 根据 digital_tube_font 确认
// 返回参数     void
// 使用示例     
// 备注信息     
//-------------------------------------------------------------------------------------------------------------------
static void display_show_number_by_index (uint8 index, uint8 display_data)
{
    DISPLAY_BIT_PORT    |=  0x0C;
    DISPLAY_DATA_PORT   |=  0xFF;
    DISPLAY_BIT_PORT    =  ((~(0x01 << (index + (DISPLAY_BIT_PIN1 & 0x0F)))) & DISPLAY_BIT_PORT);
    DISPLAY_DATA_PORT   =  display_data;
}

//-------------------------------------------------------------------------------------------------------------------
// 函数简介     显示处理 函数
// 参数说明     void
// 返回参数     void
// 使用示例     display_hanlder();
// 备注信息     
//-------------------------------------------------------------------------------------------------------------------
void display_hanlder (void)
{
    switch(charge_state)
    {
        default:
        case CHARGE_INIT:
        {
            if(display_index)
            {   // 个位固定显示‘5’ 替代 ‘S’
                display_temp = digital_tube_font[5];
            }
            else
            {   // 根据识别的电池类型显示 12V - 3S 24V - 6S
                display_temp = digital_tube_font[charge_battery_cell_count];
            }
        }break;
        case CHARGE_STANDBY:
        case CHARGE_OPEN:
        {
            if(display_index)
            {
                switch(display_mode_select)
                {
                    default:
                    case DISPLAY_MODE_DEC:              display_temp = digital_tube_font[charge_display_power % 10];        break;
                    case DISPLAY_MODE_DEC_ONE_TENTH:    display_temp = digital_tube_font[charge_display_power / 10 % 10];   break;
                    case DISPLAY_MODE_HEX:              display_temp = digital_tube_font[charge_display_power % 16];        break;
                }
            }
            else
            {
                switch(display_mode_select)
                {
                    default:
                    case DISPLAY_MODE_DEC:              display_temp = digital_tube_font[charge_display_power / 10 % 10];   break;
                    case DISPLAY_MODE_DEC_ONE_TENTH:    display_temp = digital_tube_font[charge_display_power / 100 % 10];  break;
                    case DISPLAY_MODE_HEX:              display_temp = digital_tube_font[charge_display_power / 16 % 16];   break;
                }
                if(display_temp == digital_tube_font[0])
                {
                    display_temp = digital_tube_font[17];
                }
            }
        }break;
        case CHARGE_CLOSE:
        {
            display_temp = digital_tube_font[16];
        }break;
        case CHARGE_LOW_POWER:
        {
            if(display_index)
            {
                display_temp = digital_tube_font[0];
            }
            else
            {
                display_temp = digital_tube_font[19];
            }
        }break;
        case CHARGE_ERR:
        {
            if(display_index)
            {
                display_temp = digital_tube_font[18];
            }
            else
            {
                display_temp = digital_tube_font[14];
            }
        }break;
    }
    display_show_number_by_index(display_index, display_temp);
    display_index = 1 - display_index;
}

//-------------------------------------------------------------------------------------------------------------------
// 函数简介     显示处理 初始化 主要是采样初始化
// 参数说明     void
// 返回参数     void
// 使用示例     display_init();
// 备注信息     
//-------------------------------------------------------------------------------------------------------------------
void display_init (display_mode_enum mode)
{
    gpio_mode(DISPLAY_DATA_PIN0, GPO_PP);
    gpio_mode(DISPLAY_DATA_PIN1, GPO_PP);
    gpio_mode(DISPLAY_DATA_PIN2, GPO_PP);
    gpio_mode(DISPLAY_DATA_PIN3, GPO_PP);
    gpio_mode(DISPLAY_DATA_PIN4, GPO_PP);
    gpio_mode(DISPLAY_DATA_PIN5, GPO_PP);
    gpio_mode(DISPLAY_DATA_PIN6, GPO_PP);
    gpio_mode(DISPLAY_DATA_PIN7, GPO_PP);
    DISPLAY_DATA_PORT = 0x00;

    gpio_mode(DISPLAY_BIT_PIN1, GPO_PP);
    gpio_mode(DISPLAY_BIT_PIN2, GPO_PP);
    gpio_set_level(DISPLAY_BIT_PIN1, 0);
    gpio_set_level(DISPLAY_BIT_PIN2, 0);

    display_mode_select = mode;

    display_show_number_by_index(0, 0xFF);
    display_show_number_by_index(1, 0xFF);
}
